#include "http_.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

// ========================== 工具函数 ==========================

// 跳过空白字符
static const char *skip_whitespace(const char *s) {
    while (*s && isspace((unsigned char)*s)) s++;
    return s;
}

// 将字符串转换为小写
static void str_tolower(char *str) {
    for (; *str; str++) {
        *str = tolower((unsigned char)*str);
    }
}

// 安全字符串复制（带截断）
static void str_copy(char *dest, const char *src, size_t max_len) {
    if (!src) {
        dest[0] = '\0';
        return;
    }
    
    size_t len = strlen(src);
    if (len >= max_len) {
        len = max_len - 1;
    }
    
    memcpy(dest, src, len);
    dest[len] = '\0';
}

// 解析一行 (支持\n和\r\n)
static const char *read_line(const char *ptr, const char *end, char *line, size_t max_len) {
    const char *line_start = ptr;
    const char *line_end = ptr;
    
    // 找到行结束位置
    while (line_end < end && *line_end != '\n' && (line_end - line_start) < max_len - 1) {
        line_end++;
    }
    
    // 计算行长度
    size_t len = line_end - line_start;
    if (len > 0 && *(line_end - 1) == '\r') {
        len--; // 去掉\r
    }
    
    // 复制行内容
    memcpy(line, line_start, len);
    line[len] = '\0';
    
    // 返回下一行起始位置
    return (line_end < end && *line_end == '\n') ? line_end + 1 : line_end;
}

// 解析查询参数
static void parse_query_params(http_message_t *msg, const char *query_str) {
    if (!query_str || *query_str == '\0') return;
    
    // 复制查询字符串以便处理
    char query[MAX_PATH_LEN * 2];
    str_copy(query, query_str, sizeof(query));
    
    char *token = strtok(query, "&");
    while (token && msg->query_param_count < MAX_QUERY_VALUE_LEN) { // 限制最大参数数量
        // 查找键值分隔符
        char *eq = strchr(token, '=');
        if (eq) {
            // 分割键值对
            *eq = '\0';
            char *key = token;
            char *value = eq + 1;
            
            // 分配新空间
            http_query_param_t *new_params = HTTP_REALLOC(
                msg->query_params, (msg->query_param_count + 1) * sizeof(http_query_param_t));
            
            if (!new_params) break;
            
            msg->query_params = new_params;
            http_query_param_t *param = &msg->query_params[msg->query_param_count];
            
            // 存储键值对
            str_copy(param->key, key, sizeof(param->key));
            str_copy(param->value, value, sizeof(param->value));
            
            msg->query_param_count++;
        }
        token = strtok(NULL, "&");
    }
}

// ========================== 头部字段处理 ==========================

// 将头部字段名转换为枚举值
static http_header_field_t header_field_to_enum(const char *field_name) {
    // 创建小写副本以便比较
    char lower[MAX_HEADER_NAME_LEN];
    str_copy(lower, field_name, sizeof(lower));
    str_tolower(lower);
    
    if (strcmp(lower, "host") == 0) {
        return HTTP_HEADER_HOST;
    } else if (strcmp(lower, "user-agent") == 0) {
        return HTTP_HEADER_USER_AGENT;
    } else if (strcmp(lower, "accept") == 0) {
        return HTTP_HEADER_ACCEPT;
    } else if (strcmp(lower, "content-type") == 0) {
        return HTTP_HEADER_CONTENT_TYPE;
    } else if (strcmp(lower, "content-length") == 0) {
        return HTTP_HEADER_CONTENT_LENGTH;
    } else if (strcmp(lower, "connection") == 0) {
        return HTTP_HEADER_CONNECTION;
    } else if (strcmp(lower, "cookie") == 0) {
        return HTTP_HEADER_COOKIE;
    } else if (strcmp(lower, "set-cookie") == 0) {
        return HTTP_HEADER_SET_COOKIE;
    } else if (strcmp(lower, "location") == 0) {
        return HTTP_HEADER_LOCATION;
    }  else if (strcmp(lower, "content-disposition") == 0) {
        return HTTP_HEADER_CONTENT_DISPOSITION;
    }else if (strcmp(lower, "referer") == 0) {
        return HTTP_HEADER_REFERER;
    } else if (strcmp(lower, "authorization") == 0) {
        return HTTP_HEADER_AUTHORIZATION;
    } else if (strcmp(lower, "cache-control") == 0) {
        return HTTP_HEADER_CACHE_CONTROL;
    } else if (strcmp(lower, "pragma") == 0) {
        return HTTP_HEADER_PRAGMA;
    } else if (strcmp(lower, "expires") == 0) {
        return HTTP_HEADER_EXPIRES;
    } else if (strcmp(lower, "last-modified") == 0) {
        return HTTP_HEADER_LAST_MODIFIED;
    } else if (strcmp(lower, "if-modified-since") == 0) {
        return HTTP_HEADER_IF_MODIFIED_SINCE;
    } else if (strcmp(lower, "etag") == 0) {
        return HTTP_HEADER_ETAG;
    } else if (strcmp(lower, "if-none-match") == 0) {
        return HTTP_HEADER_IF_NONE_MATCH;
    } else if (strcmp(lower, "transfer-encoding") == 0) {
        return HTTP_HEADER_TRANSFER_ENCODING;
    } else if (strcmp(lower, "upgrade") == 0) {
        return HTTP_HEADER_UPGRADE;
    } else if (strcmp(lower, "server") == 0) {
        return HTTP_HEADER_SERVER;
    } else if (strcmp(lower, "date") == 0) {
        return HTTP_HEADER_DATE;
    } else if (strcmp(lower, "range") == 0) {
        return HTTP_HEADER_RANGE;
    } else if (strcmp(lower, "accept-encoding") == 0) {
        return HTTP_HEADER_ACCEPT_ENCODING;
    } else if (strcmp(lower, "accept-language") == 0) {
        return HTTP_HEADER_ACCEPT_LANGUAGE;
    }
    
    return HTTP_HEADER_CUSTOM;
}

// 获取头部字段的字符串表示
const char *http_header_field_str(http_header_field_t field) {
    switch (field) {
        case HTTP_HEADER_HOST: return "Host";
        case HTTP_HEADER_USER_AGENT: return "User-Agent";
        case HTTP_HEADER_ACCEPT: return "Accept";
        case HTTP_HEADER_CONTENT_TYPE: return "Content-Type";
        case HTTP_HEADER_CONTENT_LENGTH: return "Content-Length";
        case HTTP_HEADER_CONNECTION: return "Connection";
        case HTTP_HEADER_COOKIE: return "Cookie";
        case HTTP_HEADER_SET_COOKIE: return "Set-Cookie";
        case HTTP_HEADER_LOCATION: return "Location";
        case HTTP_HEADER_REFERER: return "Referer";
        case HTTP_HEADER_AUTHORIZATION: return "Authorization";
        case HTTP_HEADER_CACHE_CONTROL: return "Cache-Control";
        case HTTP_HEADER_PRAGMA: return "Pragma";
        case HTTP_HEADER_EXPIRES: return "Expires";
        case HTTP_HEADER_LAST_MODIFIED: return "Last-Modified";
        case HTTP_HEADER_IF_MODIFIED_SINCE: return "If-Modified-Since";
        case HTTP_HEADER_ETAG: return "ETag";
        case HTTP_HEADER_IF_NONE_MATCH: return "If-None-Match";
        case HTTP_HEADER_TRANSFER_ENCODING: return "Transfer-Encoding";
        case HTTP_HEADER_UPGRADE: return "Upgrade";
        case HTTP_HEADER_SERVER: return "Server";
        case HTTP_HEADER_DATE: return "Date";
        case HTTP_HEADER_RANGE: return "Range";
        case HTTP_HEADER_ACCEPT_ENCODING: return "Accept-Encoding";
        case HTTP_HEADER_ACCEPT_LANGUAGE: return "Accept-Language";
        default: return "Custom";
    }
}

// ========================== 解析函数 ==========================

// 解析HTTP方法
static http_method_t parse_http_method(const char *method) {
    if (strcmp(method, "GET") == 0) return HTTP_METHOD_GET;
    if (strcmp(method, "POST") == 0) return HTTP_METHOD_POST;
    if (strcmp(method, "PUT") == 0) return HTTP_METHOD_PUT;
    if (strcmp(method, "DELETE") == 0) return HTTP_METHOD_DELETE;
    if (strcmp(method, "HEAD") == 0) return HTTP_METHOD_HEAD;
    if (strcmp(method, "OPTIONS") == 0) return HTTP_METHOD_OPTIONS;
    if (strcmp(method, "CONNECT") == 0) return HTTP_METHOD_CONNECT;
    if (strcmp(method, "TRACE") == 0) return HTTP_METHOD_TRACE;
    if (strcmp(method, "PATCH") == 0) return HTTP_METHOD_PATCH;
    return HTTP_METHOD_UNKNOWN;
}

// 解析起始行
static int parse_start_line(http_message_t *msg, char *line) {
    char *saveptr;
    char *token = strtok_r(line, " ", &saveptr);
    
    if (!token) return -1;
    
    // 判断是请求还是响应
    if (strncmp(token, "HTTP/", 5) == 0) {
        // 响应报文
        msg->type = HTTP_TYPE_RESPONSE;
        str_copy(msg->version, token, sizeof(msg->version));
        
        token = strtok_r(NULL, " ", &saveptr);
        if (!token) return -1;
        msg->status_code = atoi(token);
        
        token = strtok_r(NULL, "", &saveptr);
        if (token) {
            str_copy(msg->status_text, token, sizeof(msg->status_text));
        } else {
            msg->status_text[0] = '\0';
        }
    } else {
        // 请求报文
        msg->type = HTTP_TYPE_REQUEST;
        msg->method = parse_http_method(token);
        
        token = strtok_r(NULL, " ", &saveptr);
        if (!token) return -1;
        
        // 保存完整路径
        str_copy(msg->path, token, sizeof(msg->path));
        
        // 提取基础路径和查询参数
        char *query_start = strchr(msg->path, '?');
        if (query_start) {
            // 复制基础路径
            *query_start = '\0';
            str_copy(msg->base_path, msg->path, sizeof(msg->base_path));
            
            // 恢复原始路径
            *query_start = '?';
            
            // 解析查询参数
            parse_query_params(msg, query_start + 1);
        } else {
            // 没有查询参数
            str_copy(msg->base_path, msg->path, sizeof(msg->base_path));
        }
        
        token = strtok_r(NULL, " ", &saveptr);
        if (!token) return -1;
        str_copy(msg->version, token, sizeof(msg->version));
    }
    
    return 0;
}

// 解析头部
static int parse_header(http_message_t *msg, char *line) {
    char *colon = strchr(line, ':');
    if (!colon) return -1;
    
    *colon = '\0'; // 分割名称和值
    
    char *name = line;
    const char *value_ptr = skip_whitespace(colon + 1);
    
    // 添加新头部
    http_header_t *new_headers = HTTP_REALLOC(
        msg->headers, (msg->header_count + 1) * sizeof(http_header_t));
    
    if (!new_headers) return -1;
    
    msg->headers = new_headers;
    http_header_t *header = &msg->headers[msg->header_count];
    
    // 设置头部字段
    header->field = header_field_to_enum(name);
    
    // 复制值字符串
    str_copy(header->value, value_ptr, sizeof(header->value));
    
    msg->header_count++;
    
    return 0;
}

// 主解析函数
http_message_t *http_parse(const char *data, size_t length) {
    if (!data || length == 0) return NULL;
    
    http_message_t *msg = HTTP_CALLOC(1, sizeof(http_message_t));
    if (!msg) return NULL;
    
    const char *ptr = data;
    const char *end = data + length;
    
    // 解析起始行
    char line[MAX_PATH_LEN * 2]; // 足够长的行缓冲区
    ptr = read_line(ptr, end, line, sizeof(line));
    if (parse_start_line(msg, line) != 0) {
        http_message_free(msg);
        return NULL;
    }
    
    // 解析头部
    while (ptr < end) {
        ptr = read_line(ptr, end, line, sizeof(line));
        
        // 空行表示头部结束
        if (strlen(line) == 0) {
            break;
        }
        
        if (parse_header(msg, line) != 0) {
            http_message_free(msg);
            return NULL;
        }
    }
    
    // 解析正文
    if (ptr < end) {
        msg->body_length = end - ptr;
        if (msg->body_length > 0) {
            if (msg->body_length > MAX_BODY_LEN) {
                msg->body_length = MAX_BODY_LEN;
            }
            memcpy(msg->body, ptr, msg->body_length);
            msg->body[msg->body_length] = '\0';
        }
    }
    
    return msg;
}

// ========================== 组包函数 ==========================

// 序列化HTTP方法
const char *http_method_str(http_method_t method) {
    switch (method) {
        case HTTP_METHOD_GET: return "GET";
        case HTTP_METHOD_POST: return "POST";
        case HTTP_METHOD_PUT: return "PUT";
        case HTTP_METHOD_DELETE: return "DELETE";
        case HTTP_METHOD_HEAD: return "HEAD";
        case HTTP_METHOD_OPTIONS: return "OPTIONS";
        case HTTP_METHOD_CONNECT: return "CONNECT";
        case HTTP_METHOD_TRACE: return "TRACE";
        case HTTP_METHOD_PATCH: return "PATCH";
        default: return "UNKNOWN";
    }
}

// 主组包函数
char *http_serialize(const http_message_t *msg, size_t *out_len) {
    if (!msg) return NULL;
    
    // 计算所需缓冲区大小
    size_t len = 0;
    
    // 起始行
    if (msg->type == HTTP_TYPE_REQUEST) {
        // 使用完整路径（包含查询参数）
        len += snprintf(NULL, 0, "%s %s %s\r\n", 
                       http_method_str(msg->method), msg->path, msg->version);
    } else {
        len += snprintf(NULL, 0, "%s %d %s\r\n", 
                       msg->version, msg->status_code, msg->status_text);
    }
    
    // 头部
    for (size_t i = 0; i < msg->header_count; i++) {
        const http_header_t *h = &msg->headers[i];
        const char *field_name = http_header_field_str(h->field);
        
        len += snprintf(NULL, 0, "%s: %s\r\n", field_name, h->value);
    }
    
    // 空行
    len += 2; // \r\n
    
    // 正文
    len += msg->body_length;
    
    // 分配缓冲区
    char *buffer = HTTP_MALLOC(len + 1);
    if (!buffer) return NULL;
    buffer[len] = '\0'; // 安全起见
    
    char *ptr = buffer;
    size_t n;
    
    // 填充起始行
    if (msg->type == HTTP_TYPE_REQUEST) {
        n = snprintf(ptr, len+1, "%s %s %s\r\n", 
                    http_method_str(msg->method), msg->path, msg->version);
        ptr += n;
        len -= n;
    } else {
        n = snprintf(ptr, len+1, "%s %d %s\r\n", 
                    msg->version, msg->status_code, msg->status_text);
        ptr += n;
        len -= n;
    }
    
    // 填充头部
    for (size_t i = 0; i < msg->header_count; i++) {
        const http_header_t *h = &msg->headers[i];
        const char *field_name = http_header_field_str(h->field);
        
        n = snprintf(ptr, len+1, "%s: %s\r\n", field_name, h->value);
        ptr += n;
        len -= n;
    }
    
    // 填充空行
    n = snprintf(ptr, len+1, "\r\n");
    ptr += n;
    len -= n;
    
    // 填充正文
    if (msg->body_length > 0) {
        memcpy(ptr, msg->body, msg->body_length);
        ptr += msg->body_length;
        len -= msg->body_length;
    }
    
    *out_len = ptr - buffer;
    return buffer;
}

// ========================== 内存管理 ==========================

// 释放HTTP消息
void http_message_free(http_message_t *msg) {
    if (!msg) return;
    
    // 释放头部数组
    if (msg->headers) {
        HTTP_FREE(msg->headers);
    }
    
    // 释放查询参数数组
    if (msg->query_params) {
        HTTP_FREE(msg->query_params);
    }
    
    // 释放消息结构
    HTTP_FREE(msg);
}

// ========================== 查询参数访问函数 ==========================

// 根据键名获取查询参数值
const char *http_get_query_param(const http_message_t *msg, const char *key) {
    if (!msg || !key || msg->type != HTTP_TYPE_REQUEST) return NULL;
    
    for (size_t i = 0; i < msg->query_param_count; i++) {
        if (strcmp(msg->query_params[i].key, key) == 0) {
            return msg->query_params[i].value;
        }
    }
    
    return NULL;
}

// 根据字段枚举获取头部值
const char *http_get_header(const http_message_t *msg, http_header_field_t field) {
    if (!msg) return NULL;
    
    for (size_t i = 0; i < msg->header_count; i++) {
        if (msg->headers[i].field == field) {
            return msg->headers[i].value;
        }
    }
    
    return NULL;
}